#pragma once

#include "IRuntimeModule.hpp"
#include "Allocator.hpp"
#include <new>
#include <type_traits>

namespace My
{
    class MemoryManager : implements IRuntimeModule
    {
    public:
        template<typename T, typename... Arguments>
        T* New(Arguments... parameters)
        {
            return new (Allocate(sizeof(T))) T(Arguments);
        }
        
        template<typename T>
        void Delete(T* p)
        {
            reinterpret_cast<T*>(p)->~T();
            Free(p, sizeof(T));
        }

    public:
        virtual ~MemoryManager() {}

    public:
        virtual int Initialize() override;
        virtual void Finalize() override;
        virtual void Tick() override;

    public:
        // 根据传入的类型尺寸，分配对应的内存
        void* Allocate(size_t size);

        // 根据传入的地址和类型尺寸，销毁对应的内存
        void Free(void* p, size_t size);

    private:
        // 根据传入的尺寸和映射关系，返回对应的内存分配器
        static Allocator* LookUpAllocator(size_t size);

    private:
        static size_t*      m_pBlockSizeLookup;     // 管理内存映射的数组
        static Allocator*   m_pAllocators;          // 管理内存分配器的数组
    };
}

    // template<typename T, typename... Arguments>
    // T* New(Arguments... parameters)
    // {
    //     static_assert(std::is_constructible<T, Arguments...>::value, "Type must be constructible with the given arguments");
    //     void* memory = Allocate(sizeof(T));
    //     if (!memory) {
    //         throw std::bad_alloc();
    //     }
    //     return new (memory) T(std::forward<Arguments>(parameters)...);
    // }
    // template<typename T>
    // void Delete(T *p)
    // {
    //     if (!p) return;
    //     reinterpret_cast<T*>(p)->~T();
    //     Free(p, sizeof(T));
    // }